﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Lidgren.Network.Xna;
using System.Threading;

namespace MobMentality.Network
{
    class Server
    {
        public NetConnection other;
        public NetServer server;
        public Queue<Vector2> net_cmd = new Queue<Vector2>();

        public void SendLocation(NetServer server, NetConnection player, Vector2 loc)
        {
            NetOutgoingMessage om = server.CreateMessage();
            XNAExtensions.Write(om, loc);
            server.SendMessage(om, player, NetDeliveryMethod.Unreliable);
        }

        public void SendV4(NetServer server, NetConnection player, Vector4 loc)
        {
            NetOutgoingMessage om = server.CreateMessage();
            XNAExtensions.Write(om, loc);
            server.SendMessage(om, player, NetDeliveryMethod.Unreliable);
        }

        public void SendString(NetServer server, NetConnection player, String str)
        {
            NetOutgoingMessage om = server.CreateMessage();
            om.Write(str);
            server.SendMessage(om, player, NetDeliveryMethod.Unreliable);
        }

        public void ServerRun()
        {
            NetPeerConfiguration config = new NetPeerConfiguration("MobMentality");
            config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
            config.Port = 14242;

            // create and start server
            server = new NetServer(config);
            server.Start();

            // schedule initial sending of position updates
            double nextSendUpdates = NetTime.Now;

            // run until escape is pressed
            while (true)
            {
                NetIncomingMessage msg;
                while ((msg = server.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                        case NetIncomingMessageType.DiscoveryRequest:
                            //
                            // Server received a discovery request from a client; send a discovery response (with no extra data attached)
                            //
                            server.SendDiscoveryResponse(null, msg.SenderEndpoint);
                            break;
                        case NetIncomingMessageType.StatusChanged:
                            NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte();
                            if (status == NetConnectionStatus.Connected)
                            {
                                //
                                // A new player just connected!
                                //
                                Console.WriteLine(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " connected!");

                                // randomize his position and store in connection tag
                                msg.SenderConnection.Tag = new int[] {
									NetRandom.Instance.Next(10, 100),
									NetRandom.Instance.Next(10, 100)
								};
                            }

                            break;
                        case NetIncomingMessageType.VerboseDebugMessage:
                        case NetIncomingMessageType.DebugMessage:
                        case NetIncomingMessageType.WarningMessage:
                        case NetIncomingMessageType.ErrorMessage:
                            Console.WriteLine(msg.ReadString());
                            break;
                        case NetIncomingMessageType.Data:
                            Vector2 tmp = XNAExtensions.ReadVector2(msg);
                            Console.WriteLine(tmp);
                            net_cmd.Enqueue(tmp);
                            break;
                        default:
                            Console.WriteLine("Unhandled type: " + msg.MessageType);
                            break;

                    }

                    //
                    // send position updates 30 times per second
                    //
                    double now = NetTime.Now;
                    if (now > nextSendUpdates)
                    {
                        // Yes, it's time to send position updates

                        // for each player...
                        foreach (NetConnection player in server.Connections)
                        {
                            // ... send information about every other player (actually including self)
                            foreach (NetConnection otherPlayer in server.Connections)
                            {
                                /*
                                // send position update about 'otherPlayer' to 'player'
                                NetOutgoingMessage om = server.CreateMessage();

                                // write who this position is for
                                om.Write(otherPlayer.RemoteUniqueIdentifier);

                                if (otherPlayer.Tag == null)
                                    otherPlayer.Tag = new int[2];

                                int[] pos = otherPlayer.Tag as int[];
                                om.Write(pos[0]);
                                om.Write(pos[1]);

                                // send message
                                server.SendMessage(om, player, NetDeliveryMethod.Unreliable);
                                */
                                other = player;
                            }
                        }

                        // schedule next update
                        nextSendUpdates += (1.0 / 30.0);
                    }
                }

                // sleep to allow other processes to run smoothly
                Thread.Sleep(1);
            }

            server.Shutdown("app exiting");
        }

        public Server()
        {
            //while (!t.IsAlive) ;
        }
            
    }
}
